<template>
  <div class="user-edit-container">
    <!-- Header 区域 -->
    <van-nav-bar title="编辑资料" left-arrow @click-left="$router.back()" fixed />

    <!-- 用户资料 -->
    <van-cell-group class="action-card">
      <van-cell title="头像" is-link center>
        <template #default>
          <!-- 阿凡达 -> avatar -->
          <van-image round class="avatar" :src="profile.photo" @click="onAvatarClick" />
          <!-- 文件选择框 -->
          <input type="file" accept="image/*" class="iptFile" ref="iptFile" @change="onFileChange" />
        </template>
      </van-cell>
      <van-cell title="名称" is-link :value="profile.name" @click="isShowNameDialog = true" />
      <van-cell title="性别" is-link :value="profile.gender === 1 ? '男' : '女'" />
      <van-cell title="生日" is-link :value="profile.birthday" @click="show = true" />
    </van-cell-group>

    <!-- 修改用户名称的对话框 -->
    <van-dialog v-model="isShowNameDialog" title="修改名称" show-cancel-button @opened="onNameDialogOpened" @open="onNameDialogOpen" :before-close="onNameDialogBeforeClose">
      <van-field v-model="name" input-align="center" ref="nameIpt" maxlength="7" placeholder="请输入名称" />
    </van-dialog>

    <!-- 修改生日的动作面板 -->
    <van-action-sheet v-model="show">
      <!-- 选择出生日期 -->
      <van-datetime-picker v-model="currentDate" type="date" title="选择出生日期" :min-date="minDate" :max-date="maxDate" @cancel="onCancel" @confirm="onConfirm" />
    </van-action-sheet>
  </div>
</template>

<script>
import { getUserProfile, updateUserProfile, updateUserAvatar } from '@/api/userAPI'
import { mapMutations, mapState } from 'vuex'

export default {
  name: 'UserEdit',
  data() {
    return {
      // 是否展示修改名称的对话框
      isShowNameDialog: false,
      // 用户的名字
      name: '',
      // 控制修改生日动作面板的显示与隐藏
      show: false,
      // 当前的日期
      currentDate: new Date(),
      // 最小可选的日期
      minDate: new Date(1900, 0, 1),
      // 最大可选的日期
      maxDate: new Date(2030, 11, 31)
    }
  },
  created() {
    this.getUserProfile()
  },
  methods: {
    ...mapMutations(['updateProfile']),
    // 获取用户的简介信息
    async getUserProfile() {
      // 调用 API 接口
      const { data: res } = await getUserProfile()
      if (res.message === 'OK') {
        // 把数据存储到 Vuex 中
        this.updateProfile(res.data)
      }
    },
    // 监听修改名称对话框打开完毕的事件
    onNameDialogOpened() {
      this.$refs.nameIpt.focus()
    },
    // 监听修改名称对话框刚要打开的事件
    onNameDialogOpen() {
      this.name = this.profile.name
    },
    // 监听对话框关闭之前的事件
    // 如果在 before-close 中希望关闭 Dialog，必须、也只能调用 done() 函数，
    // 直接调用 this.isShowNameDialog = false 没有任何作用！！！
    async onNameDialogBeforeClose(action, done) {
      // action 用来表示用户点击的是哪个按钮
      // 如果值为 confirm 表示点击了确认
      // 如果值为 cancel 表示点击了取消
      // console.log(action)
      // done 是一个函数，
      // 如果调用了 done() 会直接关闭 Dialog
      // 如果调用了 done(false) 会阻止关闭 Dialog

      // 1. 名称长度不合法的情况
      if ((this.name.length === 0 || this.name.length > 7) && action === 'confirm') {
        // 提示用户名称长度不合法
        this.$notify({
          type: 'warning',
          message: '名称的长度为1-7个字符'
        })
        return done(false)
      }
      // 2. 名称长度合法的情况，发起请求
      if (action === 'confirm' && this.name.length > 0 && this.name.length <= 7) {
        try {
          // 发起请求，更新用户的名字
          const { data: res } = await updateUserProfile({ name: this.name })
          if (res.message === 'OK') {
            // 更新成功
            this.$toast('修改成功！')
            // 重新请求用户的简介信息
            this.getUserProfile()
            // 关闭 Dialog 对话框
            return done()
          }
        } catch {
          this.$notify({
            type: 'warning',
            message: '用户名被占用，请更换后重试！'
          })
          done(false)
        }
      }
      // 3. 其它的情况（例如：用户点击了取消）
      done()
    },
    // 取消了选择日期
    onCancel() {
      this.show = false
    },
    // 用户确认了日期的选择
    async onConfirm(val) {
      const dt = new Date(val)

      const y = dt.getFullYear()
      const m = (dt.getMonth() + 1).toString().padStart(2, '0')
      const d = dt.getDate().toString().padStart(2, '0')

      const dtStr = `${y}-${m}-${d}`
      // TODO：调用修改用户简介的 API 接口
      const { data: res } = await updateUserProfile({ birthday: dtStr })
      if (res.message === 'OK') {
        // 提示用户修改成功
        this.$toast.success('修改成功！')
        // 刷新用户的简介数据
        this.getUserProfile()
        // 关闭弹出层
        this.show = false
      }
    },
    // 用户点击了头像的图片
    onAvatarClick() {
      // 替用户点击一下那个被隐藏的文件选择框
      // 调用 原生DOM对象的.click()
      this.$refs.iptFile.click()
    },
    // 监听文件选择框的 change 事件
    async onFileChange(e) {
      // 1. 通过 e.target.files 获取到文件列表的伪数组
      const files = e.target.files
      // 2. 用户没有选择任何文件，直接 return
      if (files.length === 0) return

      // 3.1 创建 FormData 表单对象
      const fd = new FormData()
      // 3.2 向 FormData 实例中新增一个数据项，名字叫做 photo，值是图片的文件
      fd.append('photo', files[0])

      const { data: res } = await updateUserAvatar(fd)
      if (res.message === 'OK') {
        // 4.1 重新请求用户简介信息
        this.getUserProfile()
        // 4.2 提示用户
        this.$toast.success('更新成功！')
      }
    }
  },
  computed: {
    ...mapState(['profile'])
  }
}
</script>

<style lang="less" scoped>
.user-edit-container {
  padding-top: 46px;
  .avatar {
    width: 50px;
    height: 50px;
  }
}

.iptFile {
  display: none;
}
</style>
